#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Author:Lijiacai
Email:1050518702@qq.com
===========================================
CopyRight@JackLee.com
===========================================
"""
import datetime
import os
import sys
import json
import requests
from elasticsearch import Elasticsearch
from pandas.io.json import json_normalize
import pandas as pd
import numpy as np

cur_dir = os.path.split(os.path.realpath(__file__))[0]
sys.path.append("%s/.." % cur_dir)
import config

sys.path.append("%s/.." % cur_dir)
from res.lijiacai.utils import tool

es_cluster = config.es_cluster


class GetDataSet():
    def es_clinet(self):
        return Elasticsearch(hosts=es_cluster, port=None)

    def esDataToFrame(self, data):
        hits = data.get("hits", {}).get("hits", [])
        res = json_normalize(hits)
        res = res.drop(["_index", "_type", "_id", "_score"], axis=1)
        cols = res.columns.values.tolist()
        col_dict = {}
        for i in cols:
            col_dict[i] = i.replace("_source.", "")
        res.rename(col_dict, axis='columns', inplace=True)
        return res

    def getOrderDataSet(self, index="order_predict_dataset_v1",
                        start_time="2020-05-20 10:46:50",
                        end_time="2020-05-25 10:46:50"):
        dsl = {'query':
            {
                "bool": {
                    'must': [{'range': {
                        'REAL_RET_TIME': {'from': start_time, 'to': end_time}}}]
                }
            },
            'from': 0, 'size': 500000}
        es = self.es_clinet()
        res = es.search(index=index, body=json.dumps(dsl))
        # print(json.dumps(res, ensure_ascii=False))
        df = self.esDataToFrame(res)
        return df


class GetOrderPredict():
    mapping = {"REAL_GET_TIME": "DATE", "GET_STATION_ID": "ID"}

    def __init__(self):
        self.data = None
        self.redis_client = tool.RedisDB(**config.redis_conf).client

    def init_data_es(self, index="order_predict_dataset_v1",
                     start_time="2020-04-20 10:46:50",
                     end_time="2020-05-25 10:46:50"):
        data = GetDataSet()
        data_ = data.getOrderDataSet(index=index, start_time=start_time, end_time=end_time)
        res = data_[list(self.mapping)]
        res.rename(self.mapping, axis='columns', inplace=True)
        self.data = res

    def pre_data(self):
        self.data["DATE"] = pd.to_datetime(self.data.DATE, format="%Y/%m/%d %H:%M:%S")
        self.data["FLAG"] = 1

    def getBestStation(self, count=20):
        data = self.data[["ID"]]
        res = data.ID.value_counts().sort_values(ascending=False)
        res = res.to_frame()
        res = res.reset_index()
        res.rename({"ID": "COUNT", "index": "ID"}, axis='columns', inplace=True)
        # front20 = res.head(count)
        # front20.to_csv("./front20_getStation.csv")
        # print(list(front20.ID))
        return list(res.ID)

    def predicter(self, ID=2062, minTime=7, maxTime=9, week="Monday"):
        data = self.data.loc[self.data.ID == ID]
        data["WEEK"] = data.DATE.dt.day_name()
        weekday = data.loc[data.WEEK == week]
        timer = weekday.loc[(weekday.DATE.dt.hour >= minTime) & (weekday.DATE.dt.hour < maxTime)]
        timer.set_index("DATE", inplace=True)
        timer = timer["FLAG"].resample("7D").sum()
        timer = timer.to_frame()

        timer = timer.reset_index()
        timer = timer.sort_values(by='FLAG')
        # print(list(timer.no))
        # timer.set_index("date",inplace=True)
        median = np.median(list(timer.FLAG))
        return median

    def run(self):
        times = [[0, 3], [3, 6], [6, 9], [9, 12], [12, 15], [15, 18], [18, 21], [21, 24]]
        today = datetime.datetime.today()
        tomorrow = today + datetime.timedelta(days=1)
        week = tomorrow.weekday()
        start_time = today - datetime.timedelta(days=60)
        end_time = today
        week_mapping = {
            0: 'Monday',
            1: 'Tuesday',
            2: 'Wednesday',
            3: 'Thursday',
            4: 'Friday',
            5: 'Saturday',
            6: 'Sunday',
        }
        self.init_data_es(index=config.order_predict_dataset,
                          start_time=str(start_time.date()) + " 00:00:00",
                          end_time=str(end_time.date()) + " 00:00:00")
        self.pre_data()
        out = {}
        for i in self.getBestStation():
            for j in times:
                res = self.predicter(ID=i, minTime=j[0], maxTime=j[1], week=week_mapping[int(week)])
                if str(res) == "nan":
                    res = 0.0
                out[str(i) + "_" + f"{j[0]}-{j[1]}"] = res

        return out

    def go(self):
        res = self.run()
        self.redis_client.set("order_predict_result", json.dumps(res), ex=None, px=None, nx=False, xx=False)


if __name__ == '__main__':
    GetOrderPredict().go()
